//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//

package org.quickserver.net.server.impl;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.Method;
import java.net.SocketException;
import java.net.SocketTimeoutException;
import java.nio.channels.ClosedChannelException;
import java.nio.channels.SelectionKey;
import java.nio.channels.SocketChannel;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.net.ssl.SSLException;


import com.dykj.fireFighting.web.model.report.DevHisSs;
import com.dykj.fireFighting.web.model.report.DevHisZc;
import org.quickserver.net.AppException;
import org.quickserver.net.ConnectionLostException;
import org.quickserver.net.GB268753QN.*;
import org.quickserver.net.model.*;
import org.quickserver.net.server.AuthStatus;
import org.quickserver.net.server.ClientEvent;
import org.quickserver.net.server.ClientWriteHandler;
import org.quickserver.net.server.DataMode;
import org.quickserver.net.server.DataType;
import org.quickserver.net.server.TheClient;
import org.quickserver.util.Assertion;
import org.quickserver.util.MyString;
import org.quickserver.util.data.dataProcessing;

public class BlockingClientHandler extends BasicClientHandler {
    private static final Logger logger = Logger.getLogger(BlockingClientHandler.class.getName());

    public BlockingClientHandler(int instanceCount) {
        super(instanceCount);
    }

    public BlockingClientHandler() {
    }

    public void clean() {
        logger.log(Level.FINEST, "Starting clean - {0}", this.getName());
        super.clean();
        logger.log(Level.FINEST, "Finished clean - {0}", this.getName());
    }

    public void handleClient(TheClient theClient) throws Exception {
        super.handleClient(theClient);
    }

    protected void setInputStream(InputStream in) throws IOException {
        this.in = in;
        if (this.getDataMode(DataType.IN) == DataMode.STRING) {
            this.b_in = null;
            this.o_in = null;
            this.bufferedReader = new BufferedReader(new InputStreamReader(this.in, this.charset));
        } else if (this.getDataMode(DataType.IN) == DataMode.OBJECT) {
            this.b_in = null;
            this.bufferedReader = null;
            this.o_in = new ObjectInputStream(in);
        } else if (this.getDataMode(DataType.IN) == DataMode.BYTE || this.getDataMode(DataType.IN) == DataMode.BINARY) {
            this.o_in = null;
            this.bufferedReader = null;
            this.b_in = new BufferedInputStream(in);
        }

    }

    public BufferedReader getBufferedReader() {
        return this.bufferedReader;
    }

    public synchronized void closeConnection() {
        if (this.connection) {
            this.connection = false;

            try {
                if (!this.hasEvent(ClientEvent.MAX_CON_BLOCKING)) {
                    this.notifyCloseOrLost();
                }

                if (this.out != null) {
                    logger.finest("Closing output streams");

                    try {
                        this.out.flush();
                    } catch (IOException var2) {
                        logger.log(Level.FINEST, "Flushing output streams failed: " + var2, var2);
                    }

                    if (this.socket != null && !this.isSecure()) {
                        this.socket.shutdownOutput();
                    }

                    if (this.dataModeOUT == DataMode.OBJECT) {
                        this.o_out.close();
                    } else {
                        this.b_out.close();
                    }

                    if (this.out != null) {
                        this.out.close();
                    }
                }

                if (this.in != null) {
                    logger.finest("Closing input streams");
                    if (this.dataModeIN == DataMode.STRING) {
                        if (this.bufferedReader != null) {
                            this.bufferedReader.close();
                        }
                    } else if (this.dataModeIN == DataMode.OBJECT) {
                        this.o_in.close();
                    } else {
                        this.b_in.close();
                    }

                    if (this.in != null) {
                        this.in.close();
                    }
                }
            } catch (IOException var3) {
                logger.log(Level.WARNING, "Error in closeConnection: {0}", var3);
                if (logger.isLoggable(Level.FINE)) {
                    logger.log(Level.FINE, "StackTrace: " + var3, var3);
                }
            } catch (NullPointerException var4) {
                logger.log(Level.FINE, "NullPointerException: " + var4, var4);
            }

        }
    }

    public void run() {
        if (this.unprocessedClientEvents.isEmpty()) {
            logger.finest("No unprocessed ClientEvents!");
        } else {
            ClientEvent currentEvent = (ClientEvent)this.unprocessedClientEvents.poll();
            if (currentEvent == null) {
                threadEvent.set((Object)null);
                logger.finest("No unprocessed ClientEvents! pool was null");
            } else {
                StringBuilder sb;
                if (logger.isLoggable(Level.FINEST)) {
                    sb = new StringBuilder();
                    sb.append("Running ").append(this.getName());
                    sb.append(" using ");
                    sb.append(Thread.currentThread().getName());
                    sb.append(" for ");
                    Set var3 = this.clientEvents;
                    synchronized(this.clientEvents) {
                        if (this.clientEvents.size() > 1) {
                            sb.append(currentEvent).append(", Current Events - ").append(this.clientEvents);
                        } else {
                            sb.append(currentEvent);
                        }
                    }

                    logger.finest(sb.toString());
                }

                threadEvent.set(currentEvent);

                try {
                    if (this.socket == null) {
                        throw new SocketException("Socket was null!");
                    }

                    this.prepareForRun();
                    if (this.getThreadEvent() == ClientEvent.MAX_CON_BLOCKING) {
                        this.processMaxConnection(currentEvent);
                    }

                    try {
                        if (this.getThreadEvent() == ClientEvent.RUN_BLOCKING) {
                            this.clientEventHandler.gotConnected(this);
                            if (!this.authorised) {
                                if (this.clientAuthenticationHandler == null && this.authenticator == null) {
                                    this.authorised = true;
                                } else if (this.clientAuthenticationHandler != null) {
                                    sb = null;

                                    AuthStatus authStatus;
                                    do {
                                        authStatus = this.processAuthorisation();
                                    } while(authStatus == AuthStatus.FAILURE);

                                    if (authStatus == AuthStatus.SUCCESS) {
                                        this.authorised = true;
                                    }
                                } else {
                                    this.processAuthorisation();
                                }
                            }

                            this.processRead();
                        }
                    } catch (SocketException var7) {
                        this.appLogger.log(Level.FINEST, "SocketException - Client [{0}]: {1}", new Object[]{this.getHostAddress(), var7});
                        this.lost = true;
                    } catch (AppException var8) {
                        this.appLogger.log(Level.FINEST, "AppException {0}: {1}", new Object[]{Thread.currentThread().getName(), var8});
                    } catch (SSLException var9) {
                        this.lost = true;
                        if (Assertion.isEnabled()) {
                            this.appLogger.log(Level.INFO, "SSLException - Client [{0}] {1}: {2}", new Object[]{this.getHostAddress(), Thread.currentThread().getName(), var9});
                        } else {
                            this.appLogger.log(Level.WARNING, "SSLException - Client [{0}]: {1}", new Object[]{this.getHostAddress(), var9});
                        }
                    } catch (ConnectionLostException var10) {
                        this.lost = true;
                        if (var10.getMessage() != null) {
                            this.appLogger.log(Level.FINEST, "Connection lost {0}: {1}", new Object[]{Thread.currentThread().getName(), var10});
                        } else {
                            this.appLogger.log(Level.FINEST, "Connection lost {0}", Thread.currentThread().getName());
                        }
                    } catch (IOException var11) {
                        this.lost = true;
                        this.appLogger.log(Level.FINE, "IOError {0}: {1}", new Object[]{Thread.currentThread().getName(), var11});
                    } catch (AssertionError var12) {
                        logger.log(Level.WARNING, "[AssertionError] {0} {1}", new Object[]{this.getName(), var12});
                        if (logger.isLoggable(Level.FINEST)) {
                            logger.log(Level.FINEST, "StackTrace {0}: {1}", new Object[]{Thread.currentThread().getName(), MyString.getStackTrace(var12)});
                        }

                        this.assertionSystemExit();
                    } catch (RuntimeException var13) {
                        logger.log(Level.WARNING, "[RuntimeException] {0}", MyString.getStackTrace(var13));
                        if (Assertion.isEnabled()) {
                            this.assertionSystemExit();
                        }

                        this.lost = true;
                    } catch (Throwable var14) {
                        logger.log(Level.WARNING, "[Error] {0}", var14);
                        if (logger.isLoggable(Level.FINEST)) {
                            logger.log(Level.FINEST, "StackTrace {0}: {1}", new Object[]{Thread.currentThread().getName(), MyString.getStackTrace(var14)});
                        }

                        if (Assertion.isEnabled()) {
                            this.assertionSystemExit();
                        }

                        this.lost = true;
                    }

                    if (this.getThreadEvent() != ClientEvent.MAX_CON_BLOCKING) {
                        this.notifyCloseOrLost();
                    }

                    if (this.connection) {
                        logger.log(Level.FINEST, "{0} calling closeConnection()", Thread.currentThread().getName());
                        this.closeConnection();
                    }
                } catch (SSLException var15) {
                    logger.log(Level.WARNING, "SSLException {0}", var15);
                } catch (IOException var16) {
                    logger.log(Level.WARNING, "IOError - Closing Client: {0}", var16);
                } catch (RuntimeException var17) {
                    logger.log(Level.WARNING, "[RuntimeException] {0} {1}", new Object[]{this.getName(), MyString.getStackTrace(var17)});
                    if (Assertion.isEnabled()) {
                        this.assertionSystemExit();
                    }
                } catch (Exception var18) {
                    logger.log(Level.WARNING, "Error on Event:{0} - Socket:{1} : {2}", new Object[]{this.getThreadEvent(), this.socket, var18});
                    logger.log(Level.FINE, "StackTrace: {0}\n{1}", new Object[]{this.getName(), MyString.getStackTrace(var18)});
                    if (Assertion.isEnabled()) {
                        this.assertionSystemExit();
                    }
                } catch (Throwable var19) {
                    logger.log(Level.WARNING, "Error on - Event:{0} - Socket:{1} : {2}", new Object[]{this.getThreadEvent(), this.socket, var19});
                    logger.log(Level.FINE, "StackTrace: {0}\n{1}", new Object[]{this.getName(), MyString.getStackTrace(var19)});
                    if (Assertion.isEnabled()) {
                        this.assertionSystemExit();
                    }
                }

                try {
                    if (this.socket != null && !this.socket.isClosed()) {
                        logger.finest("Closing Socket");
                        this.socket.close();
                    }
                } catch (Exception var5) {
                    logger.log(Level.WARNING, "Error closing Socket/Channel: {0}", var5);
                }

                this.willClean = true;
                this.returnClientData();
                boolean returnClientHandler = false;
                Object var22 = this.lockObj;
                synchronized(this.lockObj) {
                    returnClientHandler = this.checkReturnClientHandler();
                }

                if (returnClientHandler) {
                    this.returnClientHandler();
                }

            }
        }
    }

    protected boolean checkReturnClientHandler() {
        return true;
    }

    private void processRead() throws IOException, ClassNotFoundException, AppException {
        AuthStatus authStatus = null;

        String rec = null;
        Object recObject = null;
        Object var5 = null;

        while(this.connection) {
            try {
                if (this.dataModeIN == DataMode.STRING) {
                    rec = this.bufferedReader.readLine();
                    if (rec == null) {
                        this.lost = true;
                        break;
                    }

                    if (this.getCommunicationLogging() && this.authorised) {
                        this.appLogger.log(Level.FINE, "Got STRING [{0}] : {1}", new Object[]{this.getHostAddress(), rec});
                    }

                    this.totalReadBytes = this.totalReadBytes + rec.length() + 2;
                    if (!this.authorised) {
                        authStatus = this.clientAuthenticationHandler.handleAuthentication(this, rec);
                    } else {
                        this.clientCommandHandler.handleCommand(this, rec);
                    }
                } else if (this.dataModeIN == DataMode.OBJECT) {
                    recObject = this.o_in.readObject();
                    if (recObject == null) {
                        this.lost = true;
                        break;
                    }

                    if (this.getCommunicationLogging() && this.authorised) {
                        this.appLogger.log(Level.FINE, "Got OBJECT [{0}] : {1}", new Object[]{this.getHostAddress(), recObject.toString()});
                    }

                    ++this.totalReadBytes;
                    if (!this.authorised) {
                        authStatus = this.clientAuthenticationHandler.handleAuthentication(this, recObject);
                    } else {
                        this.clientObjectHandler.handleObject(this, recObject);
                    }
                } else if (this.dataModeIN == DataMode.BYTE) {
                    rec = this.readBytes();
                    if (rec == null) {
                        this.lost = true;
                        break;
                    }

                    if (this.getCommunicationLogging() && this.authorised) {
                        this.appLogger.log(Level.FINE, "Got BYTE [{0}] : {1}", new Object[]{this.getHostAddress(), rec});
                    }

                    this.totalReadBytes += rec.length();
                    if (!this.authorised) {
                        authStatus = this.clientAuthenticationHandler.handleAuthentication(this, rec);
                    } else {
                        this.clientCommandHandler.handleCommand(this, rec);
                    }
                } else {
                    if (this.dataModeIN != DataMode.BINARY) {
                        throw new IllegalStateException("Incoming DataMode is not supported: " + this.dataModeIN);
                    }

                    byte[] recByte = this.readBinary();
                    if (recByte == null) {
                        this.lost = true;
                        break;
                    }

                    if (this.getCommunicationLogging() && this.authorised) {
                        if (this.getServer().isRawCommunicationLogging()) {
                            if (this.getServer().getRawCommunicationMaxLength() > 0 && recByte.length > this.getServer().getRawCommunicationMaxLength()) {
                                this.appLogger.log(Level.FINE, "Got BINARY [{0}] : {1}; RAW: {2}{3}", new Object[]{this.getHostAddress(), MyString.getMemInfo((float)recByte.length), new String(recByte, 0, this.getServer().getRawCommunicationMaxLength(), this.charset), "..."});
                            } else {
                                this.appLogger.log(Level.FINE, "Got BINARY [{0}] : {1}; RAW: {2}", new Object[]{this.getHostAddress(), MyString.getMemInfo((float)recByte.length), new String(recByte, this.charset)});
                            }
                        } else {
                            this.appLogger.log(Level.FINE, "Got BINARY [{0}] : {1}", new Object[]{this.getHostAddress(), MyString.getMemInfo((float)recByte.length)});
                        }
                    } else if (this.getCommunicationLogging()) {
                        this.appLogger.log(Level.FINE, "Got BINARY [{0}] : {1}", new Object[]{this.getHostAddress(), MyString.getMemInfo((float)recByte.length)});
                    }

                    this.totalReadBytes += recByte.length;
                    if (!this.authorised) {
                        authStatus = this.clientAuthenticationHandler.handleAuthentication(this, recByte);
                    } else {
                    	Object o=this.clientData;
                    	String s=(String) getFieldValueByName("sbType",o);
                    	if("1".equals(s)) {
                    		GBServerData gbd = (GBServerData)this.getClientData();
                            GB268753QN gbqn = analysisMain.init(this, dataProcessing.bytesToHexStrings(recByte));
                            if (gbd != null && !"0".equals(gbd.getUniqueCode()) && "0".equals(gbd.getDevState())) {
                                this.clientBinaryHandler.gotConnectDev(this, gbd.getUniqueCode());
                                gbd.setDevState("1");
                            }
                            this.clientBinaryHandler.handleGB268753QN(this, gbqn);
                    	}else if("2".equals(s)){
                    		GBServerDataS gbd = (GBServerDataS)this.getClientData();
                            GB268753QNS gbqn = analysisMainS.init(this, dataProcessing.bytesToHexStrings(recByte));
                            if (gbd != null && !"0".equals(gbd.getUniqueCode()) && "0".equals(gbd.getDevState())) {
                                this.clientBinaryHandler.gotConnectDev(this, gbd.getUniqueCode());
                                gbd.setDevState("1");
                            }
                            this.clientBinaryHandler.handleGB268753QN(this, gbqn);
                    	}else if("3".equals(s)){
                            ZCServerData gbd = (ZCServerData)this.getClientData();
                            DevHisZc gbqn = analysisMainZc.init(this, dataProcessing.bytesToHexStrings(recByte));
                            //analysisMainZc.init(this, dataProcessing.bytesToHexStrings(recByte));
                            if (gbd != null && !"0".equals(gbd.getUniqueCode()) && "0".equals(gbd.getDevState())) {
                                this.clientBinaryHandler.gotConnectDev(this, gbd.getUniqueCode());
                                gbd.setDevState("1");
                            }
                            this.clientBinaryHandler.handleGB268753QN(this, gbqn);
                        }else  if("4".equals(s)){
                            GBServerDataSZGW  gbd = (GBServerDataSZGW)this.getClientData();
                            List<GB268753QNSZGW> gbqn = analysisMainSZGW.init(this, dataProcessing.bytesToHexStrings(recByte));
                            if (gbd != null && !"0".equals(gbd.getUniqueCode()) && "0".equals(gbd.getDevState())) {
                                this.clientBinaryHandler.gotConnectDev(this, gbd.getUniqueCode());
                                gbd.setDevState("1");
                            }
                            this.clientBinaryHandler.handleGB268753QN(this, gbqn);
                        }else  if("5".equals(s)){
                            ShengShanServerData  gbd = (ShengShanServerData)this.getClientData();
                            DevHisSs gbqn = analysisMainSS.init(this, dataProcessing.bytesToHexStrings(recByte));
                            if (gbd != null && !"0".equals(gbd.getUniqueCode()) && "0".equals(gbd.getDevState())) {
                                this.clientBinaryHandler.gotConnectDev(this, gbd.getUniqueCode());
                                gbd.setDevState("1");
                            }
                            this.clientBinaryHandler.handleGB268753QN(this, gbqn);
                        }
                    }
                }

                this.updateLastCommunicationTime();

                while(authStatus == AuthStatus.FAILURE) {
                    authStatus = this.processAuthorisation();
                }

                if (authStatus == AuthStatus.SUCCESS) {
                    this.authorised = true;
                }
            } catch (SocketTimeoutException var7) {
                this.handleTimeout(var7);
            }
        }

    }

    protected void returnClientHandler() {
        logger.finest(this.getName());
        super.returnClientHandler();
    }

    public void setDataMode(DataMode dataMode, DataType dataType) throws IOException {
        if (this.getDataMode(dataType) != dataMode) {
            this.appLogger.log(Level.FINE, "Setting Type:{0}, Mode:{1}", new Object[]{dataType, dataMode});
            super.checkDataModeSet(dataMode, dataType);
            this.setDataModeBlocking(dataMode, dataType);
        }
    }

    private void setDataModeBlocking(DataMode dataMode, DataType dataType) throws IOException {
        logger.finest("ENTER");
        if (dataMode == DataMode.STRING) {
            if (dataType == DataType.OUT) {
                if (this.dataModeOUT != DataMode.BYTE && this.dataModeOUT != DataMode.BINARY) {
                    if (this.dataModeOUT == DataMode.OBJECT) {
                        this.dataModeOUT = dataMode;
                        this.o_out.flush();
                        this.o_out = null;
                        this.b_out = new BufferedOutputStream(this.out);
                    } else {
                        Assertion.affirm(false, "Unknown DataType.OUT DataMode - " + this.dataModeOUT);
                    }
                } else {
                    this.dataModeOUT = dataMode;
                }

                Assertion.affirm(this.b_out != null, "BufferedOutputStream is still null!");
            } else if (dataType == DataType.IN) {
                this.dataModeIN = dataMode;
                if (this.o_in != null) {
                    if (this.o_in.available() != 0) {
                        logger.warning("Data looks to be present in ObjectInputStream");
                    }

                    this.o_in = null;
                }

                if (this.b_in != null) {
                    if (this.b_in.available() != 0) {
                        logger.warning("Data looks to be present in BufferedInputStream");
                    }

                    this.b_in = null;
                }

                this.bufferedReader = new BufferedReader(new InputStreamReader(this.in, this.charset));
                Assertion.affirm(this.bufferedReader != null, "BufferedReader is still null!");
            }
        } else if (dataMode == DataMode.OBJECT) {
            if (dataType == DataType.OUT) {
                this.dataModeOUT = dataMode;
                if (this.b_out != null) {
                    this.b_out.flush();
                    this.b_out = null;
                }

                this.o_out = new ObjectOutputStream(this.out);
                Assertion.affirm(this.o_out != null, "ObjectOutputStream is still null!");
            } else if (dataType == DataType.IN) {
                this.dataModeIN = dataMode;
                if (this.b_in != null) {
                    if (this.b_in.available() != 0) {
                        logger.warning("Data looks to be present in BufferedInputStream");
                    }

                    this.b_in = null;
                }

                this.bufferedReader = null;
                this.o_in = new ObjectInputStream(this.in);
                Assertion.affirm(this.o_in != null, "ObjectInputStream is still null!");
            }
        } else {
            if (dataMode != DataMode.BYTE && dataMode != DataMode.BINARY) {
                throw new IllegalArgumentException("Unknown DataMode : " + dataMode);
            }

            if (dataType == DataType.OUT) {
                if (this.dataModeOUT != DataMode.STRING && this.dataModeOUT != DataMode.BYTE && this.dataModeOUT != DataMode.BINARY) {
                    if (this.dataModeOUT == DataMode.OBJECT) {
                        this.dataModeOUT = dataMode;
                        if (this.o_out != null) {
                            this.o_out.flush();
                            this.o_out = null;
                        }

                        this.b_out = new BufferedOutputStream(this.out);
                    } else {
                        Assertion.affirm(false, "Unknown DataType.OUT - DataMode: " + this.dataModeOUT);
                    }
                } else {
                    this.dataModeOUT = dataMode;
                }

                Assertion.affirm(this.b_out != null, "BufferedOutputStream is still null!");
            } else {
                if (dataType != DataType.IN) {
                    throw new IllegalArgumentException("Unknown DataType : " + dataType);
                }

                this.dataModeIN = dataMode;
                if (this.o_in != null) {
                    if (this.o_in.available() != 0) {
                        logger.warning("Data looks to be present in ObjectInputStream");
                    }

                    this.o_in = null;
                }

                this.bufferedReader = null;
                this.b_in = new BufferedInputStream(this.in);
                Assertion.affirm(this.b_in != null, "BufferedInputStream is still null!");
            }
        }

    }

    protected byte[] readInputStream() throws IOException {
        return readInputStream(this.b_in);
    }

    public void updateInputOutputStreams() throws IOException {
        this.setInputStream(this.getSocket().getInputStream());
        this.setOutputStream(this.getSocket().getOutputStream());
    }

    public boolean getBlockingMode() {
        return true;
    }

    public void setSocketChannel(SocketChannel socketChannel) {
        throw new IllegalStateException("Can't set in blocking mode!");
    }

    public SocketChannel getSocketChannel() {
        throw new IllegalStateException("Can't get in blocking mode!");
    }

    public void setSelectionKey(SelectionKey selectionKey) {
        throw new IllegalStateException("Can't set in blocking mode!");
    }

    public SelectionKey getSelectionKey() {
        throw new IllegalStateException("Can't get in blocking mode!");
    }

    public void registerForRead() throws IOException, ClosedChannelException {
        throw new IllegalStateException("Can't register in blocking mode!");
    }

    public void registerForWrite() throws IOException, ClosedChannelException {
        throw new IllegalStateException("Can't register in blocking mode!");
    }

    protected void setClientWriteHandler(ClientWriteHandler handler) {
        throw new IllegalStateException("Can't register in blocking mode!");
    }

    private Object getFieldValueByName(String fieldName, Object o) {
    	         try {
    	             String firstLetter = fieldName.substring(0, 1).toUpperCase();
               String getter = "get" + firstLetter + fieldName.substring(1);
    	             Method method = o.getClass().getMethod(getter, new Class[] {});
    	             Object value = method.invoke(o, new Object[] {});
    	             return value;
    	         } catch (Exception e) {
    	             return null;
    	         }
    	     }
}
